package com.orange.project.client.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.orange.common.base.entity.AppInfo;
import com.orange.common.base.entity.IpVo;
import com.orange.common.base.service.impl.BaseServiceImpl;
import com.orange.common.constant.HeaderConstants;
import com.orange.common.constant.ServiceConstants;
import com.orange.common.enums.ResultCodeEnum;
import com.orange.common.exception.BusinessException;
import com.orange.common.page.PageParam;
import com.orange.common.page.PageResult;
import com.orange.common.page.PageUtils;
import com.orange.common.utils.IdsUtils;
import com.orange.common.utils.IpUtil;
import com.orange.common.utils.MD5Utils;
import com.orange.common.utils.ProdIdGenerateUtil;
import com.orange.project.client.mapper.ClientMapper;
import com.orange.project.client.mapper.ClientShareMapper;
import com.orange.project.client.mapper.LoginClientMapper;
import com.orange.project.client.pojo.*;
import com.orange.project.client.service.ClientService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * TODO
 *
 * @Author YWF
 * @Date 2025/8/14 9:44
 */
@Service
public class ClientServiceImpl extends BaseServiceImpl<ClientMapper, ClientDto> implements ClientService {

    protected final static Logger logger = LoggerFactory.getLogger(ClientServiceImpl.class);

    @Autowired
    private ClientMapper clientMapper;

    @Autowired
    private LoginClientMapper loginClientMapper;

    @Autowired
    private ClientShareMapper clientShareMapper;

    @Override
    public ClientRes saveClientInfo(ClientReq clientReq) {
        LambdaQueryWrapper<ClientDto> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(ClientDto::getDeviceId, clientReq.getDeviceId());
        ClientDto clientDto = clientMapper.selectOne(queryWrapper);
        // 如果没有数据，就插入新数据
        if (ObjectUtil.isNull(clientDto)) {
            clientDto = new ClientDto();
            BeanUtil.copyProperties(clientReq, clientDto);
            clientMapper.insert(clientDto);
            Integer id = clientDto.getId();
            ProductInfo productInfo = this.generateProductId(id, clientReq.getDeviceId());
            clientDto.setUIds(productInfo.getUIds());
            clientDto.setProductId(productInfo.getProductId());
            // 更新用户uID
            clientMapper.updateById(clientDto);
        }
        ClientRes clientRes = new ClientRes();
        clientRes.setUIds(clientDto.getUIds());
        clientRes.setProductId(clientDto.getProductId());
        return clientRes;
    }

    private ProductInfo generateProductId(Integer serviceId, String fingerprintID) {
        String uids = IdsUtils.encode(serviceId);
        ProdIdGenerateUtil.Metadata metadata = new ProdIdGenerateUtil.Metadata(
                fingerprintID,
                uids
        );
        String appKey = getRequest().getHeader(HeaderConstants.X_APPKEY);
        AppInfo appInfo = redisCache.hget(appInfoCacheKey, appKey);
        String appSecret = appInfo.getAppSecret();
        String productId = ProdIdGenerateUtil.generateKey(ServiceConstants.OS_PRODUCT_PREFIX, appSecret, metadata);
        logger.info("产品信息-->uids: {}, productId: {}", uids, productId);
        return new ProductInfo(uids, productId);
    }

    @Override
    @Async("asyncServiceExecutor")
    public void saveClientLog(ClientReq clientReq) {
        LambdaQueryWrapper<ClientDto> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(ClientDto::getDeviceId, clientReq.getDeviceId());
        ClientDto clientDto = clientMapper.selectOne(queryWrapper);
        // 保存登录日志
        if (ObjectUtil.isNull(clientDto)) {
            if (ObjectUtil.isNull(clientDto)) {
                throw new BusinessException(ResultCodeEnum.CLIENT_NOT_EXISTS);
            }
        }
        String remoteIP = clientReq.getRemoteIP();
        IpVo ipAddr = IpUtil.getIpVo(remoteIP);
        logger.info("IP信息：{}, 局域网IP:{}", ipAddr, remoteIP);
        LoginClientDto loginClientDto = new LoginClientDto();
        loginClientDto.setClientID(clientDto.getId());
        loginClientDto.setIp(ipAddr.getIp());
        loginClientDto.setProvinceCode(ipAddr.getProCode());
        loginClientDto.setCityCode(ipAddr.getCityCode());
        loginClientDto.setAddr(ipAddr.getAddr());
        loginClientMapper.insert(loginClientDto);
    }

    @Override
    @Async("asyncServiceExecutor")
    public void saveClientShare(ClientShareReq clientShareReq) {
        LambdaQueryWrapper<ClientDto> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(ClientDto::getUIds, clientShareReq.getUids());
        ClientDto clientDto = clientMapper.selectOne(queryWrapper);
        if (ObjectUtil.isNull(clientDto)) {
            throw new BusinessException(ResultCodeEnum.CLIENT_NOT_EXISTS);
        }
        ClientShareDto clientShareDto = new ClientShareDto();
        BeanUtil.copyProperties(clientShareReq, clientShareDto);
        clientShareDto.setClientID(clientDto.getId());
        clientShareMapper.insert(clientShareDto);
    }

    @Override
    public PageResult<ClientShareRes> getShareList(ClientShareReq clientShareReq, PageParam pageParam) {
        System.out.println("已经执行到这儿");
        LambdaQueryWrapper<ClientShareDto> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(ClientShareDto::getUids, clientShareReq.getUids());
        queryWrapper.eq(StringUtils.isNotBlank(clientShareReq.getLangId()), ClientShareDto::getLangId, clientShareReq.getLangId());
        PageResult<ClientShareRes> pageResult = PageUtils.handleQueryAndConvert(
                pageParam,
                page -> clientShareMapper.selectPage(page, queryWrapper),
                this::convertToVO
        );
        logger.info("查询结果：{}", pageResult);
        return pageResult;
    }


    @Override
    public PageResult<ClientShareRes> findList(ClientShareReq clientShareReq, PageParam pageParam) {
        LambdaQueryWrapper<ClientShareDto> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(ClientShareDto::getUids, clientShareReq.getUids());
        queryWrapper.eq(StringUtils.isNotBlank(clientShareReq.getLangId()), ClientShareDto::getLangId, clientShareReq.getLangId());
        Page<ClientShareDto> clientShareDtoPage = clientShareMapper.selectPage(pageParam.toPage(), queryWrapper);
        PageResult<ClientShareRes> pageResult = PageUtils.convertResult(clientShareDtoPage,this::convertToVO );
        logger.info("查询结果：{}", pageResult);
        return pageResult;
    }

    private ClientShareRes convertToVO(ClientShareDto clientShareDto) {
        ClientShareRes clientShareRes = new ClientShareRes();
        BeanUtil.copyProperties(clientShareDto, clientShareRes);
        // 其他字段转换...
        return clientShareRes;
    }


    @Override
    public TranslateRes translate(TranslateReq translateReq) {
        String rs = null;
        try {
            String appid = "20250412002330680";
            String securityKey = "7AEsDiWrjpDO2HvsIBSj";
            String query = translateReq.getQuery();
            Map<String, Object> map = new HashMap<>();
            map.put("q", query);
            map.put("from", translateReq.getFrom());
            map.put("to", translateReq.getTo());
            map.put("appid", appid);
            String salt = String.valueOf(System.currentTimeMillis());
            map.put("salt", salt);
            String src = appid + query + salt + securityKey;
            String sign = MD5Utils.md5(src);
            map.put("sign", sign);
            rs = httpAPIService.doGet("https://fanyi-api.baidu.com/api/trans/vip/translate", map);
            System.out.println("rs:" + rs);

            ObjectMapper mapper = new ObjectMapper();
            TranslateRes result = mapper.readValue(rs, TranslateRes.class);
            System.out.println("translateRes:" + result);
        } catch (Exception e) {
            throw new BusinessException(ResultCodeEnum.GET_NEWS_ERROR);
        }
        return null;
    }
}
